package com.cssw.fyzb.core.eao.acct;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.core.es.EsClient;
import com.cssw.fyzb.core.model.eos.LiveRedPackSubEo;
import com.cssw.fyzb.core.model.eos.RedPackLogEo;
import com.cssw.fyzb.core.util.DateUtil;
import com.ydn.dbframe.plugin.activerecord.Page;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author Jian Qin.
 */
@Component
public class RedPackLogEaoImpl implements RedPackLogEao{
    @Autowired
    private EsClient esClient;

    private final static String INDEX_NAME = "fyzb_red_pack_log";
    private final static String TYPE_NAME = "red_pack_log";

    @Override
    public void save(Long redPackId, Long userId, String packType, String changeType,
                     BigDecimal money, String tradeId, String tradeType, String tradeName) {
        RedPackLogEo redPackLogEo = new RedPackLogEo();
        redPackLogEo.setRedPackId(redPackId);
        redPackLogEo.setType(packType);
        redPackLogEo.setMoney(money);
        redPackLogEo.setUserId(userId);
        redPackLogEo.setMoney(money);
        redPackLogEo.setTradeId(tradeId);
        redPackLogEo.setTradeName(tradeName);
        redPackLogEo.setTradeType(tradeType);
        redPackLogEo.setChangeType(changeType);
        redPackLogEo.setCreateTime(DateUtil.format(new Date()));


        esClient.getClient()
                .prepareIndex(INDEX_NAME, TYPE_NAME)
                .setSource(JSON.parseObject(JSON.toJSONString(redPackLogEo)))
                .get()
        ;
    }

    @Override
    public Page<RedPackLogEo> listLog(Long userId, Integer pageNumber, Integer pageSize) {
        pageNumber = pageNumber - 1;

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter().add(QueryBuilders.termQuery("userId", userId));

        SearchResponse response = esClient.getClient()
                .prepareSearch(INDEX_NAME)
                .setTypes(TYPE_NAME)
                .setQuery(queryBuilder)
                .setFrom(pageNumber * (pageSize - 1))
                .setSize(pageSize)
                .addSort(
                        SortBuilders.fieldSort("createTime").order(SortOrder.DESC)
                ).get();

        return toPage(response, pageNumber, pageSize);
    }

    @Override
    public Page<RedPackLogEo> listRecieveLogById(Long redPackId, String changeType, Integer pageNumber, Integer pageSize) {
        pageNumber = pageNumber - 1;

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter().add(QueryBuilders.termQuery("redPackId", redPackId));
        queryBuilder.filter().add(QueryBuilders.termQuery("type", "1"));
        queryBuilder.filter().add(QueryBuilders.termQuery("changeType", changeType));

        SearchResponse response = esClient.getClient()
                .prepareSearch(INDEX_NAME)
                .setTypes(TYPE_NAME)
                .setQuery(queryBuilder)
                .setFrom(pageNumber * (pageSize - 1))
                .setSize(pageSize)
                .addSort(
                        SortBuilders.fieldSort("createTime").order(SortOrder.DESC)
                ).get();

        return toPage(response, pageNumber, pageSize);
    }

    @Override
    public Page<RedPackLogEo> listPersonSendPack(Long fromUserId, Integer pageNumber, Integer pageSize) {
        pageNumber = pageNumber - 1;

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter().add(QueryBuilders.termQuery("userId", fromUserId));
        queryBuilder.filter().add(QueryBuilders.termQuery("type", "2"));
        queryBuilder.filter().add(QueryBuilders.termQuery("changeType", "1"));

        SearchResponse response = esClient.getClient()
                .prepareSearch(INDEX_NAME)
                .setTypes(TYPE_NAME)
                .setQuery(queryBuilder)
                .setFrom(pageNumber * (pageSize - 1))
                .setSize(pageSize)
                .addSort(
                        SortBuilders.fieldSort("createTime").order(SortOrder.DESC)
                ).get();

        return toPage(response, pageNumber, pageSize);
    }

    @Override
    public RedPackLogEo queryPersonRecieve(Long redPackId, Long userId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter().add(QueryBuilders.termQuery("userId", userId));
        queryBuilder.filter().add(QueryBuilders.termQuery("redPackId", redPackId));
        queryBuilder.filter().add(QueryBuilders.termQuery("type", "1"));
        queryBuilder.filter().add(QueryBuilders.termQuery("changeType", "1"));

        SearchResponse response = esClient.getClient()
                .prepareSearch(INDEX_NAME)
                .setTypes(TYPE_NAME)
                .setQuery(queryBuilder)
                .setSize(1)
                .get();

        if(response.getHits().totalHits > 0){
            SearchHit hit = response.getHits().getAt(0);
            return JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()), RedPackLogEo.class);
        }

        return null;
    }

    private Page<RedPackLogEo> toPage(SearchResponse response, int pageNumber, int pageSize) {
        Page<RedPackLogEo> page = new Page<>();
        int count = (int) response.getHits().totalHits;
        page.setTotalPage((int) Math.ceil(count * 1.0 / pageSize));
        page.setTotalRow(count);
        page.setPageNumber(pageNumber);
        page.setPageSize(pageSize);
        List<RedPackLogEo> list = new ArrayList<>();
        for (SearchHit hit : response.getHits()) {
            list.add(JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()), RedPackLogEo.class));
        }
        page.setList(list);
        return page;
    }
}
